#include "PthreadPoolCplus.h"

using namespace std;

TPthreadPool CPthreadPool::m_tPthreadpool;

CPthreadPool::CPthreadPool()
{

}

CPthreadPool::~CPthreadPool()
{

}

void* CPthreadPool::thread_routine(void* arg)
{
	TPthreadPoolWork work;
	pthread_detach(pthread_self());//设为线程推出自动释放资源
    while(true)
    {						
         pthread_mutex_lock(&m_tPthreadpool.queue_lock);	 
		
		 if(1 == m_tPthreadpool.pthread_id_map[pthread_self()])
         {
             pthread_mutex_unlock(&m_tPthreadpool.queue_lock);
			 printf("线程已置为可推出状态\n");
             pthread_exit(NULL);
         }

         while((0 == m_tPthreadpool.VecWork.size()) && !m_tPthreadpool.shutdown)
         {
			//当任务容器中任务个数为零进行缩容.当当前工作者线程>初始的默认工作者线程,即进行缩容
			if(m_tPthreadpool.now_thr_num >  DEFAULT_THR_NUM)
            {
                pool_del_pthread();
                if (1 == m_tPthreadpool.pthread_id_map[pthread_self()])
                {
                    pthread_mutex_unlock(&m_tPthreadpool.queue_lock);
                    printf("thread %u will exit\n", pthread_self());
                    pthread_exit(NULL);
                }
            }
							
            pthread_cond_wait(&m_tPthreadpool.queue_ready,&m_tPthreadpool.queue_lock);

         }
			
		 printf("m_tPthreadpool.VecWork.size():%d,m_tPthreadpool.now_thr_num:%d,  CPthreadPool::pool_pthread()\n",m_tPthreadpool.VecWork.size(),m_tPthreadpool.now_thr_num);
		 //销毁线程标识为1,推出线程
         if(m_tPthreadpool.shutdown)
         {
             pthread_mutex_unlock(&m_tPthreadpool.queue_lock);
             pthread_exit(NULL);
         }
			
		 //当工作者线程数量少于任务容器的任务数量时,线程池进行扩容.
		 if((m_tPthreadpool.now_thr_num < m_tPthreadpool.VecWork.size())&& m_tPthreadpool.now_thr_num < MAX_THR_NUM)
		 {
			pool_add_pthread();
		 }	
		
		std::vector<TPthreadPoolWork>::iterator iter = m_tPthreadpool.VecWork.begin();
		work = *iter;
		m_tPthreadpool.VecWork.erase(iter);

		pthread_mutex_unlock(&m_tPthreadpool.queue_lock);
		
		
		work.routine(work.arg);		
	
        //释放线程池内已空闲工作者线程
		//pool_refree_pthread();
    }
	return NULL;	
}

//创建线程池
int CPthreadPool::pool_create()
{

 	//线程池默认大小
    m_tPthreadpool.now_thr_num =DEFAULT_THR_NUM;
	
	//线程持销毁状态初始为0
	m_tPthreadpool.shutdown =0;

    //初始化线程锁
    if(pthread_mutex_init(&m_tPthreadpool.queue_lock,NULL) !=0)
    {
        printf("%s pthread_mutex_init failure, strno:%d, error:%s.\n",__FUNCTION__,errno,strerror(errno));
        exit(0);
    }

    //初始化线程锁
    if(pthread_cond_init(&m_tPthreadpool.queue_ready,NULL) !=0)
    {
        printf("%s pthread_cond_init failure, strno: %d, error:%s. \n",__FUNCTION__,errno,strerror(errno));
        exit(0);
    }
	
    //创建工作者线程
    for(int i =0; i <DEFAULT_THR_NUM; i++)
    {
        pthread_t tempThread;
        if(pthread_create(&tempThread,NULL,CPthreadPool::thread_routine,NULL) !=0)
        {
            printf("%s pthread_create failed, errno: %d , error: %s.",__FUNCTION__,errno,strerror(errno));
            exit(1);
        }
        m_tPthreadpool.pthread_id_map[tempThread] = 0; 
		printf("thread_create(): %d\n",i);
    }

	return 0;
	
}

//销毁线程池
void CPthreadPool::pool_destroy()
{

    TPthreadPoolWork *member =NULL;
    if(m_tPthreadpool.shutdown)
    {
        return;
    }

    m_tPthreadpool.shutdown =1;
    /*通知所有共作者线程*/
    pthread_mutex_lock(&m_tPthreadpool.queue_lock);
    pthread_cond_broadcast(&m_tPthreadpool.queue_ready);
    pthread_mutex_unlock(&m_tPthreadpool.queue_lock);

    //销毁工作者线程
    for(std::map<pthread_t,int>::iterator iter =m_tPthreadpool.pthread_id_map.begin(); iter !=m_tPthreadpool.pthread_id_map.end(); iter++)
    {
         pthread_join(iter->first,NULL);
    }


    pthread_mutex_destroy(&m_tPthreadpool.queue_lock);
    pthread_cond_destroy(&m_tPthreadpool.queue_ready);

}

//当工作者线程不足时增加工作者线程
void CPthreadPool::pool_add_pthread()
{
    for(int i =0; i <DEFAULT_THR_ADD; i++)
    {
        pthread_t tempThread;
        if(pthread_create(&tempThread,NULL,thread_routine,NULL) !=0)
        {
            printf("%s pthread_create failed, errno: %d , error: %s.",__FUNCTION__,errno,strerror(errno));
            exit(1);
        }
        m_tPthreadpool.pthread_id_map[tempThread] = 0;
    }
    m_tPthreadpool.now_thr_num += DEFAULT_THR_ADD;

	printf("m_tPthreadpool.VecWork.size():%d,m_tPthreadpool.now_thr_num:%d,  CPthreadPool::pool_add_pthread()\n",m_tPthreadpool.VecWork.size(),m_tPthreadpool.now_thr_num);
}

//当工作者线程过多时减少工作者线程
void CPthreadPool::pool_del_pthread()
{
	int i =0;
    //将空闲工作者线程状态置为可退出
    /*此处作用仍不明了*/
    pthread_cond_broadcast(&m_tPthreadpool.queue_ready);

	//此处注意在缩容时,要对未纳入缩容队列的工作者线程进行缩容
    for(map<pthread_t,int>::iterator iter =m_tPthreadpool.pthread_id_map.begin();  iter !=m_tPthreadpool.pthread_id_map.end(); iter++)
    {
		//检查未被纳入到缩容队类中的工作者线程,如果此处不做约束,将重复的将已列入缩容队列的工作者线程重复设置,造成内存泄漏
		if(iter->second == 0)
		{
			i++;
        	iter->second = 1;
			printf("pthread_t:%u\n",iter->first);
			if(i == DEFAULT_THR_DEL)
			{
				break;
			}
		}
    }

    m_tPthreadpool.now_thr_num -= DEFAULT_THR_DEL;

	printf("m_tPthreadpool.VecWork.size():%d,m_tPthreadpool.now_thr_num:%d,  CPthreadPool::pool_del_pthread()\n",m_tPthreadpool.VecWork.size(),m_tPthreadpool.now_thr_num);
}

//释放已被退出的工作者线程 pthread_detach(pthread_self()) 已由此函数实现
/*
void CPthreadPool::pool_refree_pthread()
{
    for(map<pthread_t,int>::iterator iter = m_tPthreadpool.pthread_id_map.begin(); iter !=m_tPthreadpool.pthread_id_map.end();iter++)
    {
        if(iter->second == 1)
        {
            pthread_join(iter->first,NULL);
        }
    }
}
*/
//向线程池添加任务
int CPthreadPool::pool_add_work(void* (*routine)(void*),void *arg)
{
    TPthreadPoolWork work;

    work.routine =routine;
    work.arg =arg;
    work.next =NULL;

    //加锁
    pthread_mutex_lock(&m_tPthreadpool.queue_lock);

    m_tPthreadpool.VecWork.push_back(work);

    pthread_mutex_unlock(&m_tPthreadpool.queue_lock);
    pthread_cond_signal(&m_tPthreadpool.queue_ready);

}

























